package net.asfun.jvalog.domain;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.jdo.Query;

import net.asfun.jvalog.except.InteractException;
import net.asfun.jvalog.po.Label;
import net.asfun.jvalog.po.Relation;
import net.asfun.jvalog.service.Jdoer;
import net.asfun.jvalog.service.JdoerFactory;
import net.asfun.jvalog.task.UpdateManager;
import net.asfun.jvalog.view.PagerInfo;
import net.asfun.jvalog.view.SiteInfo;

public class Tag {

	private Label label;
	
	private List<Relation> posts;
	
	public Tag() {
		label = new Label();
	}
	
	private Tag(Label lab) {
		if ( null == lab ) {
			throw new InteractException("Tag not found");
		}
		label = lab;
	}
	
	public static List<Tag> listAll() {
		List<Tag> list = new ArrayList<Tag>();
		Jdoer<Label> dbl = JdoerFactory.getLabelJdo();
		Collection<Label> clt = dbl.all();
		for (Label label : clt) {
			Tag tag = new Tag(label);
			list.add(tag);
		}
		return list;
	}
	
	private void setPosts() {
		if ( null == posts ) {
			posts = Bridge.getRelationsByRight(label.getKey(), Bridge.POST_TAG);
		}
	}
	
	public int getPostCount() {
		return Counter.getCount(label.getKey());
	}

	protected static Label locate(String likes) {
		Jdoer<Label> dbl = JdoerFactory.getLabelJdo();
		Query q = dbl.prepareQuery();
		q.setFilter("name == likes");
		q.declareParameters("String likes");
		Label label = dbl.unique(q, likes);
		if ( label == null ) {
			label = new Label();
			label.setName(likes);
			label.setSlogan(likes);
			dbl.save(label);
			Unifier.setUnique(label.getKey(), "slogan", likes);
		}
		return label;
	}
	
	public static void remove(Long id) {
		Jdoer<Label> dbl = JdoerFactory.getLabelJdo();
		Label label = dbl.load(id);
		if (label != null) {
			Unifier.unsetUnique(label.getKey(), "slogan");
			dbl.delete(Bridge.getRelationsByRight(label.getKey(), Bridge.POST_TAG));
			dbl.delete(label);
			UpdateManager.enableCacheTask();
		}
	}
	
	public static Tag load(Long id) {
		Tag tag = new Tag();
		Jdoer<Label> dbl = JdoerFactory.getLabelJdo();
		tag.label = dbl.load(id);
		return tag;
	}
	
	public String getName() {
		return label.getName();
	}
	
	public String getSlogan() {
		return label.getSlogan();
	}
	
	public void mergeTo(Long id) {
		if (label != null) {
			Tag tag = Tag.load(id);
			if (tag.label != null) {
				setPosts();
				for(Relation rel : posts) {
					rel.setRight(tag.label.getKey());
				}
				Jdoer<Label> dbl = JdoerFactory.getLabelJdo();
				dbl.delete(label);
			}
		}
	}
	
	public Long getId() {
		return label.getKey().getId();
	}

	public static Tag load(String slogan) {
		Jdoer<Label> dbl = JdoerFactory.getLabelJdo();
		Query query = dbl.prepareQuery();
		query.setFilter("slogan == slog");
		query.declareParameters("String slog");
		return new Tag(dbl.unique(query, slogan));
	}

	public void setName(String name) {
		label.setName(name);
	}
	
	public void setSlogan(String slogan) {
		label.setSlogan(slogan);
	}

	public void update() {
		//make sure slogan unique
		if ( ! Unifier.isUnique(label.getKey(), "slogan", label.getSlogan()) ) {
			label.setSlogan(label.getSlogan() + "~1");
			this.update();
			return ;
		}
		Unifier.setUnique(label.getKey(), "slogan", label.getSlogan());
		UpdateManager.enableCacheTask();
	}

	public List<Post> listPublishedPosts(PagerInfo pager) {
		pager.setTotal(getPostCount());
		List<Post> list = new ArrayList<Post>();
		int j=0;
		setPosts();
		for(int i=posts.size(); i>0; ) {
			Post post = Post.load(posts.get(--i).getLeft().getId());
			if ( post != null && post.isPublished() ) {
				//paging
				if ( j >= pager.getStart() && 
						j < pager.getEnd() ) {
					list.add(post);
				}
				j++;
			}
		}
		if ( list.isEmpty() && pager.getIndex() > 1 ) {
			throw new InteractException("Tag pager no record");
		}
		return list;
	}

	public String getLink() {
		return SiteInfo.getInstance().getUrl() + "tag/" + label.getSlogan();
	}
}
